export function bind({ camera, renderer, interactMeshes }) {
  var isUserInteracting = false,
    lon = 90,
    lat = 0;

  var raycaster = new THREE.Raycaster();
  var mouse = new THREE.Vector2();
  // 鼠标控制
  let onPointerDownPointerX = 0;
  let onPointerDownPointerY = 0;
  let onPointerDownLon = 0;
  let onPointerDownLat = 0;

  function onDocumentMouseDown(event) {
    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(interactMeshes);
    intersects.forEach((item) => {
      item.object.onClick?.(item);
    });
    isUserInteracting = true;
    onPointerDownPointerX = event.clientX;
    onPointerDownPointerY = event.clientY;
    onPointerDownLon = lon;
    onPointerDownLat = lat;
  }

  function onDocumentTouchDown(event) {
    isUserInteracting = true;
    onPointerDownPointerX = event.touches[0].pageX;
    onPointerDownPointerY = event.touches[0].pageY;
    onPointerDownLon = lon;
    onPointerDownLat = lat;
  }

  function onDocumentMouseMove(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    if (isUserInteracting === true) {
      lon = (onPointerDownPointerX - event.clientX) * 0.1 + onPointerDownLon;
      lat = (event.clientY - onPointerDownPointerY) * 0.1 + onPointerDownLat;
    }
  }

  function onDocumentTouchMove(event) {
    if (isUserInteracting === true) {
      lon =
        (onPointerDownPointerX - event.touches[0].pageX) * 0.1 +
        onPointerDownLon;
      lat =
        (event.touches[0].pageY - onPointerDownPointerY) * 0.1 +
        onPointerDownLat;
    }
  }

  function onDocumentMouseUp(event) {
    isUserInteracting = false;
  }

  function onDocumentMouseWheel(event) {
    camera.fov += event.deltaY * 0.05;
    camera.updateProjectionMatrix();
  }

  window.addEventListener("mousedown", onDocumentMouseDown, false);
  window.addEventListener("mousemove", onDocumentMouseMove, false);
  window.addEventListener("mouseup", onDocumentMouseUp, false);

  window.addEventListener("touchstart", onDocumentTouchDown, false);
  window.addEventListener("touchmove", onDocumentTouchMove, false);
  window.addEventListener("touchend", onDocumentMouseUp, false);

  window.addEventListener("mousewheel", onDocumentMouseWheel, false);

  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }

  window.addEventListener("resize", onWindowResize, false);

  function onKeyDown(e) {
    switch (e.code) {
      case "ArrowUp":
        camera.position.z++;
        break;
      case "ArrowLeft":
        camera.position.x++;
        break;
    }
    // console.log(e, camera.position);
  }
  window.addEventListener("keydown", onKeyDown, false);

  function getPosition() {
    return {
      lon,
      lat,
    };
  }

  function setPosition({ lon: x, lat: y }) {
    lon = x;
    lat = y;
  }

  function unbind() {
    window.removeEventListener("mousedown", onDocumentMouseDown, false);
    window.removeEventListener("mousemove", onDocumentMouseMove, false);
    window.removeEventListener("mouseup", onDocumentMouseUp, false);
    window.removeEventListener("touchstart", onDocumentTouchDown, false);
    window.removeEventListener("touchmove", onDocumentTouchMove, false);
    window.removeEventListener("touchend", onDocumentMouseUp, false);

    window.removeEventListener("mousewheel", onDocumentMouseWheel, false);

    window.removeEventListener("resize", onWindowResize, false);
  }

  function lookAt(x, y, z, fov) {
    // camera.target.x = x;
    // camera.target.y = y;
    // camera.target.z = z;
    const target = new THREE.Vector3(x, y, z);
    camera.lookAt(target);
    camera.updateProjectionMatrix();
  }

  function cameraUpdate() {
    let { lon, lat } = getPosition();

    lat = Math.max(-85, Math.min(85, lat));
    const phi = THREE.Math.degToRad(90 - lat);
    const theta = THREE.Math.degToRad(lon);

    const x = 500 * Math.sin(phi) * Math.cos(theta);
    const y = 500 * Math.cos(phi);
    const z = 500 * Math.sin(phi) * Math.sin(theta);
    lookAt(x, y, z);
    setPosition({ lat, lon });
    // camera.updateProjectionMatrix();
  }

  function fovJian() {
    camera.fov -= 1;
    camera.updateProjectionMatrix();
  }

  function reset() {
    camera.fov = 75;
    camera.updateProjectionMatrix();
  }

  return {
    getPosition,
    setPosition,
    unbind,
    cameraUpdate,
    lookAt,
    fovJian,
    reset,
  };
}
